package com.example.huadu_server.user.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.StpUtil;
import com.example.huadu_server.config.Response;
import com.example.huadu_server.user.entity.User;
import com.example.huadu_server.user.mapper.UserMapper;
import com.example.huadu_server.user.service.UserAuthService;
import com.google.code.kaptcha.Producer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class UserAuthServiceImpl implements UserAuthService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private UserMapper userMapper;

    private static final String REDIS_KEY_PREFIX = "REGISTER_CODE_";

    @Value("${spring.mail.username}")  // 从配置文件中注入发件人邮箱
    private String senderEmail;

     /*
         注册
     */

    @Override
    public Response<String> sendRegisterCode(String email) {
        // 生成6位随机验证码
        String code = String.format("%06d", new Random().nextInt(1000000));

        // 存储到 Redis，有效期5分钟
        redisTemplate.opsForValue().set(REDIS_KEY_PREFIX + email, code, 5, TimeUnit.MINUTES);

        // 发送邮件
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(senderEmail); // 发件人地址，必须与配置一致
        message.setTo(email); // 收件人地址
        message.setSubject("花都优居平台");
        message.setText("您的验证码是：" + code + "，用于注册，有效期为5分钟。");

        try {
            mailSender.send(message);
            // 返回带验证码的响应
            return new Response<>(200, "验证码已发送到邮箱，请查收", code);
        } catch (Exception e) {
            // 返回失败响应
            return new Response<>(500, "发送邮件失败，请稍后再试", null);
        }
    }

    @Override
    public Response<String> register(String email, String code, String password) {
        // 验证验证码
        String redisCode = redisTemplate.opsForValue().get(REDIS_KEY_PREFIX + email);
        if (redisCode == null || !redisCode.equals(code)) {
            // 返回验证码无效或过期的错误
            return new Response<>(400, "验证码无效或已过期", null);
        }

        // 检查邮箱是否已注册
        User existingUser = userMapper.selectByEmail(email);
        if (existingUser != null) {
            // 返回邮箱已被注册的错误
            return new Response<>(409, "邮箱已被注册", null);
        }

        // 创建新用户并保存到数据库
        User newUser = new User();
        newUser.setEmail(email);
        newUser.setPassword(BCrypt.hashpw(password, BCrypt.gensalt())); // 加密密码
        newUser.setUsername("用户" + System.currentTimeMillis()); // 随机生成用户名
//        newUser.setLogo("https111111"); //默认头像
        newUser.setStatus("normal"); // 设置状态为正常

        int rows = userMapper.insert(newUser);
        if (rows == 0) {
            // 返回注册失败的错误
            return new Response<>(500, "用户注册失败", null);
        }

        // 删除 Redis 中的验证码
        redisTemplate.delete(REDIS_KEY_PREFIX + email);

        // 返回注册成功的响应
        return new Response<>(200, "注册成功", null);
    }

    /*
         登录
     */

    @Autowired
    private Producer kaptchaProducer;

    /**
     * 生成登录验证码
     */
    @Override
    public void generateLoginCode( HttpServletResponse response) {
        // 生成验证码
        String captchaText = kaptchaProducer.createText();
        String redisKey = REDIS_KEY_PREFIX;

        // 存储验证码到 Redis，有效期为 5 分钟
        redisTemplate.opsForValue().set(redisKey, captchaText, 5, TimeUnit.MINUTES);

        // 生成验证码图片
        BufferedImage image = kaptchaProducer.createImage(captchaText);

        // 设置响应头
        response.setContentType("image/jpeg");
        try {
            ImageIO.write(image, "jpeg", response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 用户登录逻辑
     */
    @Override
    public Response<Map<String, Object>> login(String email, String password, String code) {
        String redisKey = REDIS_KEY_PREFIX;

        // 从 Redis 获取验证码
        String sessionCode = redisTemplate.opsForValue().get(redisKey);
        if (sessionCode == null || !sessionCode.equalsIgnoreCase(code)) {
            // 验证码错误或过期时，删除 Redis 中的验证码（防止暴力破解）
            redisTemplate.delete(redisKey);
            return new Response<>(400, "验证码错误或已过期", null);
        }

        // 验证用户信息
        User user = userMapper.selectByEmail(email);
        if (user == null) {
            return new Response<>(404, "用户不存在", null);
        }

        // 检查用户状态是否正常
        if (!"normal".equalsIgnoreCase(user.getStatus())) {
            return new Response<>(423, "您的账号已被禁用", null);
        }

        // 验证密码
        if (!BCrypt.checkpw(password, user.getPassword())) {
            return new Response<>(402, "密码错误", null);
        }

        // 清除 Redis 中的验证码（成功验证后）
        redisTemplate.delete(redisKey);

        // 使用 Sa-Token 生成登录会话
        StpUtil.login(user.getId());

        // 获取 Token 信息
        String token = StpUtil.getTokenValue();

        // 构造返回数据
        Map<String, Object> responseData = new HashMap<>();
        responseData.put("satoken", token);
        responseData.put("id", user.getId());
        responseData.put("name", user.getUsername());

        // 返回登录成功信息
        return new Response<>(200, "登录成功", responseData);
    }


}
